package org.example.io.nio;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NIOSelectorServerSocket implements Runnable{
    Selector selector;
    ServerSocketChannel serverSocketChannel;

    public NIOSelectorServerSocket() throws IOException {
        this.selector = Selector.open();
        serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.socket().bind(new InetSocketAddress(8088));
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    }

    public static void main(String[] args) throws IOException {
        NIOSelectorServerSocket nioSelectorServer = new NIOSelectorServerSocket();
        nioSelectorServer.run();
    }

    @Override
    public void run() {
        try {
            while(true){
                selector.select();
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                System.out.println("当前连接数量：" + selectionKeys.size());
                Iterator<SelectionKey> iterator = selectionKeys.iterator();
                while (iterator.hasNext()){
                    // 对连接进行处理
                    dispatch(iterator.next());
                    iterator.remove();
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void dispatch(SelectionKey selectionKey) throws IOException {
        if(selectionKey.isAcceptable()){
            // 注册
            register(selectionKey);
        }else if(selectionKey.isReadable()){
            // 读事件
            read(selectionKey);
        }else if(selectionKey.isWritable()){
            // 写事件
        }
    }

    void register(SelectionKey selectionKey) throws IOException {
        ServerSocketChannel channel= (ServerSocketChannel) selectionKey.channel(); //客户端连接
        SocketChannel socketChannel=channel.accept(); //获得客户端连接
        socketChannel.configureBlocking(false);
        socketChannel.register(selector,SelectionKey.OP_READ);
    }
    private void read(SelectionKey key) throws IOException {
        //得到的是socketChannel
        SocketChannel channel= (SocketChannel) key.channel();
        ByteBuffer byteBuffer=ByteBuffer.allocate(1024);
        channel.read(byteBuffer);
        System.out.println("Server Receive Msg:"+new String(byteBuffer.array()));
    }
}
